package com.msimple.order.application;

import com.msimple.order.domain.model.Order;
import com.msimple.order.domain.model.OrderFactory;
import com.msimple.order.domain.model.OrderProductItem;
import com.msimple.order.facade.OrderPaymentService;
import com.msimple.order.repository.OrderRepository;
import com.msimple.sdk.command.order.ChangeProductCountCommand;
import com.msimple.sdk.command.order.CreateOrderCommand;
import com.msimple.sdk.command.order.PayOrderCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 *  order application service
 * @Title:      OrderApplicationService
 * @Package:    OrderApplicationService
 * @Author:     M.simple
 * @Remark:     The modified content
 * @CreateDate: 2019-10-13 15:41
 * @Version:    v2.0
 */
@Slf4j
@Component
public class OrderApplicationService {

    private final OrderRepository orderRepository;
    private final OrderFactory orderFactory;
    private final OrderPaymentService orderPaymentService;

    public OrderApplicationService(OrderRepository orderRepository,
                                   OrderFactory orderFactory,
                                   OrderPaymentService orderPaymentService) {
        this.orderRepository = orderRepository;
        this.orderFactory = orderFactory;
        this.orderPaymentService = orderPaymentService;
    }

    /**
     * create order info
     * @method      createOrder
     * @param       command:
     * @return      String
     * @author      M.simple
     * @date        2019-10-13 16:05
     * @version     v2.0
     */
    @Transactional
    public String createOrder(CreateOrderCommand command) {
        
        List<OrderProductItem> items = command.getItems().stream()
                .map(item -> OrderProductItem.create(item.getProductId(),
                        item.getCount(),
                        item.getItemPrice()))
                .collect(Collectors.toList());

        //1.create order
        Order order = orderFactory.create(items, command.getAddress());
        orderRepository.save(order);

        //2.payment
        log.info("Created order[{}].", order.getId());
        return order.getId();
    }

    /**
     * change order product count
     * @method      changeOrderProductCount
     * @param       id:command
     * @return      
     * @author      M.simple
     * @date        2019-10-13 16:05
     * @version     v2.0
     */
    @Transactional
    public void changeOrderProductCount(String id, ChangeProductCountCommand command) {
        
        Order order = orderRepository.byId(id);
        order.changeProductCount(command.getProductId(), command.getCount());
        
        orderRepository.save(order);
    }

    /**
     * order payment
     * @method      orderPay
     * @param       id:command
     * @return      
     * @author      M.simple
     * @date        2019-10-13 16:07
     * @version     v2.0
     */
    @Transactional
    public void orderPay(String id, PayOrderCommand command) {
        Order order = orderRepository.byId(id);
        
        orderPaymentService.pay(order, command.getPaidPrice());
        orderRepository.save(order);
    }

    /**
     * chage order address detail
     * @method      changeAddressDetail
     * @param       id:detail
     * @return      
     * @author      M.simple
     * @date        2019-10-13 16:08
     * @version     v2.0
     */
    @Transactional
    public void changeAddressDetail(String id, String detail) {
        Order order = orderRepository.byId(id);
        
        order.changeAddressDetail(detail);
        orderRepository.save(order);
    }
}
